﻿namespace DslEditorPowerToy.Controls
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;

    internal class LeafedHostedEditorControl : UserControl, IMonitorSelection, ISelectionService
    {
        private HostedEditor _currentEditor;
        private Dictionary<Guid, HostedEditor> _editors = new Dictionary<Guid, HostedEditor>();
        private NavigationOrientationStyle _navigationStyle = NavigationOrientationStyle.Vertical;
        private const int ButtonInnerPaddingX = 3;
        private const int ButtonInnerPaddingY = 2;
        private IContainer components = null;
        private const int ControlMarginX = 1;
        private const int ControlMarginY = 2;
        public const int EditorImageHeight = 0x10;
        public const int EditorImageWidth = 0x10;
        private Label emptyLabel;
        private Panel hostPanel;
        private ToolStrip toolbar;
        private ToolStripComboBox toolStripComboBox;
        private ToolStripLabel toolStripLabel;

        public event EventHandler EditorChanged;

        public event EventHandler SelectionChanged;

        public event EventHandler SelectionChanging;

        public LeafedHostedEditorControl()
        {
            this.InitializeComponent();
            ProfessionalColorTable professionalColorTable = new ProfessionalColorTable {
                UseSystemColors = true
            };
            this.toolbar.Renderer = new ToolStripProfessionalRenderer(professionalColorTable);
            this.toolStripComboBox.Margin = new Padding(1, 2, 1, 2);
            this.InitialiseControls();
        }

        private void _editor_SelectionChanged(object sender, EventArgs e)
        {
            this.OnSelectionChanged();
        }

        private void _editor_SelectionChanging(object sender, EventArgs e)
        {
            this.OnSelectionChanging();
        }

        public void ActivateEditor(Guid editorId)
        {
            if (!this._editors.ContainsKey(editorId))
            {
                throw new ArgumentOutOfRangeException(Resources.EditorNotFoundException);
            }
            HostedEditor editor = this._editors[editorId];
            if (this._currentEditor != editor)
            {
                if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
                {
                    ((ISelectionService) this._currentEditor.Control).SelectionChanged -= new EventHandler(this._editor_SelectionChanged);
                    ((ISelectionService) this._currentEditor.Control).SelectionChanging -= new EventHandler(this._editor_SelectionChanging);
                }
                if (editor.Control is ISelectionService)
                {
                    ((ISelectionService) editor.Control).SelectionChanged += new EventHandler(this._editor_SelectionChanged);
                    ((ISelectionService) editor.Control).SelectionChanging += new EventHandler(this._editor_SelectionChanging);
                }
                this._currentEditor = editor;
                this.SetActiveEditorControls();
                this.OnEditorChanged();
                this.OnSelectionChanged();
            }
        }

        public void AddEditor(HostedEditor editor)
        {
            if (editor == null)
            {
                throw new ArgumentNullException(Resources.EditorNullException);
            }
            if (editor.Control == null)
            {
                throw new ArgumentNullException(Resources.EditorControlNullException);
            }
            if (this._editors.ContainsKey(editor.Id))
            {
                throw new ArgumentOutOfRangeException(Resources.DuplicateEditorException);
            }
            this._editors.Add(editor.Id, editor);
            Bitmap image = this.EnsureIcon(editor.Image, this._editors.Count);
            ToolStripButton button = new ToolStripButton(editor.Caption, image, new EventHandler(this.toolbarItem_Click)) {
                CheckOnClick = true,
                DisplayStyle = ToolStripItemDisplayStyle.None,
                ImageTransparentColor = Color.FromKnownColor(KnownColor.Magenta),
                Tag = editor,
                Margin = new Padding(1, 2, 1, 2),
                Padding = new Padding(3, 2, 3, 2),
                Visible = false
            };
            this.toolbar.Items.Add(button);
            this.toolStripComboBox.Items.Add(editor);
            this.hostPanel.Controls.Add(editor.Control);
            editor.Control.Dock = DockStyle.Fill;
            editor.Control.Hide();
            this.SetToolBarOrientation();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private Bitmap EnsureIcon(Bitmap bitmap, int index)
        {
            Bitmap bitmap3;
            try
            {
                Rectangle rect = new Rectangle(0, 0, 0x10, 0x10);
                RectangleF layoutRectangle = new RectangleF(0f, 0f, (float) rect.Width, (float) rect.Height);
                using (Font font = new Font(FontFamily.GenericSansSerif, 10f, FontStyle.Bold))
                {
                    Brush windowText = SystemBrushes.WindowText;
                    Pen pen = SystemPens.WindowText;
                    if (bitmap == null)
                    {
                        Bitmap image = new Bitmap(rect.Width, rect.Height);
                        using (Graphics graphics = Graphics.FromImage(image))
                        {
                            graphics.DrawString(index.ToString(), font, windowText, layoutRectangle);
                            graphics.DrawRectangle(pen, 0, 0, rect.Width - 1, rect.Height - 1);
                            return image;
                        }
                    }
                    using (Graphics graphics2 = Graphics.FromImage(bitmap))
                    {
                        if ((bitmap.Height > 0x10) || (bitmap.Width > 0x10))
                        {
                            graphics2.DrawImage(bitmap, rect);
                        }
                        bitmap3 = bitmap;
                    }
                }
            }
            catch (Exception)
            {
                bitmap3 = bitmap;
            }
            return bitmap3;
        }

        public bool GetComponentSelected(object component)
        {
            return (((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService)) && (this._currentEditor.Control as ISelectionService).GetComponentSelected(component));
        }

        private List<ToolStripButton> GetEditorButtons()
        {
            List<ToolStripButton> list = new List<ToolStripButton>();
            foreach (ToolStripItem item in this.toolbar.Items)
            {
                if ((item is ToolStripButton) && (item.Tag is HostedEditor))
                {
                    list.Add(item as ToolStripButton);
                }
            }
            return list;
        }

        public ICollection GetSelectedComponents()
        {
            if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
            {
                return (this._currentEditor.Control as ISelectionService).GetSelectedComponents();
            }
            return null;
        }

        private void InitialiseControls()
        {
            this.emptyLabel.Show();
            this.hostPanel.Hide();
            this.SetToolBarOrientation();
        }

        private void InitializeComponent()
        {
            this.emptyLabel = new Label();
            this.hostPanel = new Panel();
            this.toolbar = new ToolStrip();
            this.toolStripLabel = new ToolStripLabel();
            this.toolStripComboBox = new ToolStripComboBox();
            this.toolbar.SuspendLayout();
            base.SuspendLayout();
            this.emptyLabel.BackColor = Color.Transparent;
            this.emptyLabel.Dock = DockStyle.Fill;
            this.emptyLabel.ForeColor = SystemColors.GrayText;
            this.emptyLabel.Location = new Point(0, 0);
            this.emptyLabel.Name = "emptyLabel";
            this.emptyLabel.Size = new Size(0x19f, 0x130);
            this.emptyLabel.TabIndex = 0;
            this.emptyLabel.Text = "No editors to display";
            this.emptyLabel.TextAlign = ContentAlignment.MiddleCenter;
            this.hostPanel.BackColor = Color.Transparent;
            this.hostPanel.Dock = DockStyle.Fill;
            this.hostPanel.Location = new Point(0, 0);
            this.hostPanel.Name = "hostPanel";
            this.hostPanel.Size = new Size(0x19f, 0x130);
            this.hostPanel.TabIndex = 1;
            this.toolbar.CanOverflow = false;
            this.toolbar.GripStyle = ToolStripGripStyle.Hidden;
            this.toolbar.Items.AddRange(new ToolStripItem[] { this.toolStripLabel, this.toolStripComboBox });
            this.toolbar.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
            this.toolbar.Location = new Point(0, 0);
            this.toolbar.Name = "toolbar";
            this.toolbar.RenderMode = ToolStripRenderMode.Professional;
            this.toolbar.Size = new Size(0x19f, 0x1d);
            this.toolbar.TabIndex = 0;
            this.toolbar.TabStop = true;
            this.toolStripLabel.Name = "toolStripLabel";
            this.toolStripLabel.Size = new Size(0x26, 0x1a);
            this.toolStripLabel.Text = "Views:";
            this.toolStripComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
            this.toolStripComboBox.Name = "toolStripComboBox";
            this.toolStripComboBox.Size = new Size(0x79, 0x15);
            this.toolStripComboBox.SelectedIndexChanged += new EventHandler(this.toolStripComboBox_SelectedIndexChanged);
            base.AutoScaleDimensions = new SizeF(6f, 13f);
            base.AutoScaleMode = AutoScaleMode.Font;
            base.Controls.Add(this.toolbar);
            base.Controls.Add(this.hostPanel);
            base.Controls.Add(this.emptyLabel);
            base.Name = "LeafedEditorHost";
            base.Size = new Size(0x19f, 0x130);
            this.toolbar.ResumeLayout(false);
            this.toolbar.PerformLayout();
            base.ResumeLayout(false);
            base.PerformLayout();
        }

        public virtual void NotifySelectionChanged(ISelectionProvider selectionProvider, SelectionChangeSource source)
        {
            foreach (KeyValuePair<Guid, HostedEditor> pair in this._editors)
            {
                if (pair.Value.Control is IMonitorSelection)
                {
                    (pair.Value.Control as IMonitorSelection).NotifySelectionChanged(selectionProvider, source);
                }
            }
        }

        protected void OnEditorChanged()
        {
            if (this.EditorChanged != null)
            {
                this.EditorChanged(this, new EventArgs());
            }
        }

        protected override void OnGotFocus(EventArgs e)
        {
            if (this.hostPanel.Visible)
            {
                this.hostPanel.Focus();
            }
            else if (this.emptyLabel.Visible)
            {
                this.emptyLabel.Focus();
            }
            base.OnGotFocus(e);
        }

        protected void OnSelectionChanged()
        {
            if (this.SelectionChanged != null)
            {
                this.SelectionChanged(this, new EventArgs());
            }
        }

        protected void OnSelectionChanging()
        {
            if (this.SelectionChanging != null)
            {
                this.SelectionChanging(this, new EventArgs());
            }
        }

        private void SetActiveEditorControls()
        {
            this.hostPanel.Show();
            this.emptyLabel.Hide();
            foreach (KeyValuePair<Guid, HostedEditor> pair in this._editors)
            {
                pair.Value.Control.Hide();
            }
            if (this._currentEditor != null)
            {
                this._currentEditor.Control.Show();
            }
            this.SyncEditorControls();
        }

        public void SetSelectedComponents(ICollection components)
        {
            if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
            {
                (this._currentEditor.Control as ISelectionService).SetSelectedComponents(components);
            }
        }

        public void SetSelectedComponents(ICollection components, SelectionTypes selectionType)
        {
            if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
            {
                (this._currentEditor.Control as ISelectionService).SetSelectedComponents(components, selectionType);
            }
        }

        private void SetToolBarOrientation()
        {
            DockStyle none = DockStyle.None;
            ToolStripLayoutStyle horizontalStackWithOverflow = ToolStripLayoutStyle.HorizontalStackWithOverflow;
            ToolStripItemDisplayStyle imageAndText = ToolStripItemDisplayStyle.None;
            bool flag = false;
            switch (this._navigationStyle)
            {
                case NavigationOrientationStyle.HorizontalList:
                    none = DockStyle.Top;
                    horizontalStackWithOverflow = ToolStripLayoutStyle.HorizontalStackWithOverflow;
                    imageAndText = ToolStripItemDisplayStyle.None;
                    flag = false;
                    break;

                case NavigationOrientationStyle.HorizontalTabsTop:
                    none = DockStyle.Top;
                    horizontalStackWithOverflow = ToolStripLayoutStyle.HorizontalStackWithOverflow;
                    imageAndText = ToolStripItemDisplayStyle.ImageAndText;
                    flag = true;
                    break;

                case NavigationOrientationStyle.HorizontalTabsBottom:
                    none = DockStyle.Bottom;
                    horizontalStackWithOverflow = ToolStripLayoutStyle.HorizontalStackWithOverflow;
                    imageAndText = ToolStripItemDisplayStyle.ImageAndText;
                    flag = true;
                    break;

                case NavigationOrientationStyle.Vertical:
                    none = DockStyle.Left;
                    horizontalStackWithOverflow = ToolStripLayoutStyle.VerticalStackWithOverflow;
                    imageAndText = ToolStripItemDisplayStyle.Image;
                    flag = true;
                    break;
            }
            this.toolbar.Dock = none;
            this.toolbar.LayoutStyle = horizontalStackWithOverflow;
            foreach (ToolStripButton button in this.GetEditorButtons())
            {
                button.DisplayStyle = imageAndText;
                button.Visible = flag;
            }
            this.toolStripComboBox.Visible = NavigationOrientationStyle.HorizontalList == this._navigationStyle;
            this.toolStripLabel.Visible = NavigationOrientationStyle.HorizontalList == this._navigationStyle;
            if (this.ShowingToolBar)
            {
                this.toolbar.Show();
                this.hostPanel.Padding = new Padding(0, 0, 0, 0);
            }
            else
            {
                this.hostPanel.Padding = new Padding(0, 0, 0, 0);
                this.toolbar.Hide();
            }
        }

        private void SyncEditorControls()
        {
            this.toolStripComboBox.SelectedItem = this._currentEditor;
            foreach (ToolStripButton button in this.GetEditorButtons())
            {
                button.Checked = false;
                if ((button.Tag as HostedEditor) == this._currentEditor)
                {
                    button.Checked = true;
                }
            }
        }

        private void toolbarItem_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripButton)
            {
                ToolStripButton button = sender as ToolStripButton;
                if (button.Tag is HostedEditor)
                {
                    this.ActivateEditor(((HostedEditor) button.Tag).Id);
                }
            }
        }

        private void toolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            object selectedItem = this.toolStripComboBox.SelectedItem;
            if ((selectedItem != null) && (selectedItem is HostedEditor))
            {
                this.ActivateEditor(((HostedEditor) selectedItem).Id);
            }
        }

        public HostedEditor CurrentEditor
        {
            get
            {
                return this._currentEditor;
            }
        }

        public NavigationOrientationStyle NavigationStyle
        {
            get
            {
                return this._navigationStyle;
            }
            set
            {
                this._navigationStyle = value;
                this.SetToolBarOrientation();
            }
        }

        public object PrimarySelection
        {
            get
            {
                if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
                {
                    return (this._currentEditor.Control as ISelectionService).PrimarySelection;
                }
                return null;
            }
        }

        public int SelectionCount
        {
            get
            {
                if ((this._currentEditor != null) && (this._currentEditor.Control is ISelectionService))
                {
                    return (this._currentEditor.Control as ISelectionService).SelectionCount;
                }
                return 0;
            }
        }

        protected bool ShowingToolBar
        {
            get
            {
                return (this._editors.Count > 1);
            }
        }
    }
}

